#ifndef _LOG_DEF_H_
#define _LOG_DEF_H_

#ifdef __cplusplus
extern "C" {
#endif

#if defined (__linux__)
#include <pthread.h>

#include <semaphore.h>
extern sem_t log_sem;

extern pthread_mutex_t mutex;
#define  log_output_lock(x)        pthread_mutex_lock(&mutex)
#define  log_output_unlock(x)      pthread_mutex_unlock(&mutex)
#elif defined (_WIN32)
#define  log_output_lock(x)
#define  log_output_unlock(x)
#else

static inline int _irqsave(void)
{
    int state = 0;
    int temp = 0;

    asm volatile(
        "MRS  %0, cpsr \n"
        :"=r" (state)::
    );

    asm volatile(
        "MRS  %0, cpsr \n"
        "ORR  %0, #0x80 \n"
        "MSR  cpsr_c, %0 \n"
        :"=r" (temp)::
    );

    return state;
}

static inline void _irqrestore(int state)
{
    asm volatile(
        "MSR  cpsr, %0 \n"
        ::"r" (state):
    );
}

#define  log_output_lock(x)     do { x = _irqsave();} while(0)
#define  log_output_unlock(x)   do {_irqrestore(x);}  while(0)

extern uint32_t itpGetTickCount(void);
#define  LOG_TICK_GET(x)        itpGetTickCount()
#endif

extern struct log _syslog;

#define LOG_BUFF_SIZE 8196U
#define LOG_PACK_SIZE 128U

#define LOG_LVL_ASSERT   0
#define LOG_LVL_ERROR    1
#define LOG_LVL_WARNING  2
#define LOG_LVL_INFO     3
#define LOG_LVL_DBG      4
#define LOG_LVL_MAX      5

#if !defined(LOG_TAG)
        #define LOG_TAG                "NO_TAG"
#endif /* !defined(LOG_TAG) */

#if !defined(LOG_LVL)
        #define LOG_LVL                LOG_LVL_MAX
#endif /* !defined(LOG_TAG) */

#if (LOG_LVL >= LOG_LVL_DBG)
    #define log_d(TAG,...)           log_output(LOG_LVL_DBG, TAG, __VA_ARGS__)
#else
    #define log_d(TAG,...)
#endif

#if (LOG_LVL >= LOG_LVL_INFO)
    #define log_i(TAG,...)           log_output(LOG_LVL_INFO, TAG, __VA_ARGS__)
#else
    #define log_i(TAG,...)
#endif

#if (LOG_LVL >= LOG_LVL_WARNING)
    #define log_w(TAG,...)           log_output(LOG_LVL_WARNING, TAG, __VA_ARGS__)
#else
    #define log_w(TAG,...)
#endif

#if (LOG_LVL >= LOG_LVL_ERROR)
    #define log_e(TAG,...)           log_output(LOG_LVL_ERROR, TAG, __VA_ARGS__)
#else
    #define log_e(TAG,...)
#endif

#if (LOG_LVL >= LOG_LVL_ASSERT)
    #define log_a(TAG,...)           log_output(LOG_LVL_ASSERT, TAG, __VA_ARGS__)
#else
    #define log_a(TAG,...)
#endif

#ifdef __cplusplus
}
#endif

#endif /* _LOG_DEF_H */

